from celery import shared_task
from apps.HttpTestcase.models import Testsuite
from apps.HttpTestcase.core.utils import get_version
import threading
from apps.HttpTestcase.core.http_dlient import HttpSession
from apps.HttpTestcase.core.http_testsuite_run import HttpTestsuiteRun
from apps.HttpTestcase.models.testcase_reports import TestcaseReports
from apps.HttpTestcase.models.testcases import Testcases
from apps.HttpTestcase.models.testcase_testsuite_reports import TestsuiteTestcaseReports
from apps.HttpTestcase.core.http_global_variable_pool import Variable_Pool


def run_testsuite(testsuite=None, version=None):
    for testsuite in testsuite:
        project = testsuite.project
        # 获取场景集所属项目环境
        envs = project.default_envs
        # 创建全局变量池实例
        http_global_variable = Variable_Pool()
        # 4创建HttpSession实例
        http_session = HttpSession()
        # 5创建HttpTestcaseRunner实例
        http_testsuite_run = HttpTestsuiteRun(project=project, envs=envs, testsuite=testsuite,
                                              http_session=http_session, http_global_variable=http_global_variable)

        testsuite_reports, testcase_reports_list = http_testsuite_run.run()
        testsuite_reports.version = version

        # 拿到用例列表，更新测试用例报告及用例状态
        testcase_list = []
        for testcase_report in testcase_reports_list:
            testcase_report.testsuite_reports = testsuite_reports
            testcase_report.version = version
            testcase = testcase_report.testcase
            testcase.status = testcase_report.status
            testcase_list.append(testcase)

        # 新增保存结果到场景下用例结果
        testsuite_testcase_reports = {
            'testcase_name': '',
            'api_name': '',
            'url': '',
            'actual_status_code': '',
            'elapsed_ms': '',
            'actual_response_data': '',
            'failure_reason': '',
            'testcase_id': '',
            'status': '',
            'testsuite_reports': '',
            'version':''

        }
        suite_case_reports_list = []
        for suite_case_reports in testcase_reports_list:
            testsuite_testcase_reports['testcase_name'] = suite_case_reports.testcase_name
            testsuite_testcase_reports['api_name'] = suite_case_reports.api_name
            testsuite_testcase_reports['url'] = suite_case_reports.url
            testsuite_testcase_reports['actual_status_code'] = suite_case_reports.actual_status_code
            testsuite_testcase_reports['elapsed_ms'] = suite_case_reports.elapsed_ms
            testsuite_testcase_reports['actual_response_data'] = suite_case_reports.actual_response_data
            testsuite_testcase_reports['failure_reason'] = suite_case_reports.failure_reason
            testsuite_testcase_reports['testcase_id'] = suite_case_reports.testcase_id
            testsuite_testcase_reports['status'] = suite_case_reports.status
            testsuite_testcase_reports['testsuite_reports'] = suite_case_reports.testsuite_reports
            testsuite_testcase_reports['version'] = version
            testsuite_testcase_reports['execute_time'] = suite_case_reports.execute_time
            testsuite_testcase_reports['project_name'] = suite_case_reports.project_name
            suite_testcase_reports = TestcaseReports(**testsuite_testcase_reports)
            suite_case_reports_list.append(suite_testcase_reports)


        # 1、保存场景结果
        testsuite_reports.save()
        # 2、更新场景状态
        testsuite.status = testsuite_reports.status
        testsuite.save()

        # 保存场景下用例结果
        TestsuiteTestcaseReports.objects.bulk_create(suite_case_reports_list)

        TestcaseReports.objects.bulk_create(testcase_reports_list)
        Testcases.objects.bulk_update(testcase_list, fields=['status'])


@shared_task(name="批量执行测试场景:apps.CeleryTimedTask.HttpTestcase.testsuite_task.batch_exec_testsuite")
def batch_exec_testsuite(testsuites=None, version=None):
    pass
    if not version:
        version = get_version()

    if isinstance(testsuites, str):
        testsuites = eval(testsuites) if isinstance(eval(testsuites), list) else []
    testsuite_list = Testsuite.objects.filter(id__in=testsuites, is_delete=False)

    # 线程数量
    thread_num = 5
    # Q每个线程多少任务   R剩余
    Q, R = divmod(len(testsuite_list), thread_num)

    # 生成线程对应数量的列表
    testcases_temp = [[] for i in range(thread_num)]

    # 每次取出Q个用例放入testcases_temp里的list中
    for i in range(thread_num):
        testcases_temp[i] = testsuite_list[i * Q:(i + 1) * Q]

    for i in range(R):
        testcases_temp[i].append(testsuite_list[Q * R + i])

    # 给线程分配任务并启动
    threads = []
    for y in range(thread_num):
        t = threading.Thread(target=run_testsuite, args=(testcases_temp[y], version))
        threads.append(t)

    for t in threads:
        t.start()
